/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * ClientApp.java
 *
 * Created on Nov 14, 2011, 7:56:44 AM
 */
package client;

import java.lang.reflect.InvocationTargetException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import market.MarketItem;
import market.MarketItemImpl;
import utils.MarketTableModel;

/**
 *
 * @author julio
 */
public class ClientUI extends javax.swing.JFrame implements ClientResponsiveUI {
    ClientImpl client;
    MarketTableModel postedItemsModel;
    MarketTableModel wishItemsModel;
    MarketTableModel allItemsModel;
    MarketTableModel soldItemsModel;
    MarketTableModel boughtItemsModel;
    //private ConnectDialog dialog = new ConnectDialog(this, true);

    public ClientUI(String[] args) {
        initComponents();

        // Init model and tables
        postedItemsModel = new MarketTableModel(new ArrayList<MarketItem>());
        postedItemTable.setModel(postedItemsModel);

        wishItemsModel = new MarketTableModel(new ArrayList<MarketItem>());
        wishTable.setModel(wishItemsModel);

        allItemsModel = new MarketTableModel(new ArrayList<MarketItem>());
        allItemsTable.setModel(allItemsModel);

        soldItemsModel = new MarketTableModel(new ArrayList<MarketItem>());
        soldItemsTable.setModel(soldItemsModel);

        boughtItemsModel = new MarketTableModel(new ArrayList<MarketItem>());
        boughtItemsTable.setModel(boughtItemsModel);

        try {
            client = new ClientImpl(this, args);
        } catch (RemoteException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane3 = new javax.swing.JScrollPane();
        allItemsTable = new javax.swing.JTable();
        refreshListBtn = new javax.swing.JButton();
        buyBtn = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        postedItemTable = new javax.swing.JTable();
        priceTxt = new javax.swing.JTextField();
        itemNameTxt = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        postItemBtn = new javax.swing.JButton();
        unpostItemBtn = new javax.swing.JButton();
        jPanel2 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        wishTable = new javax.swing.JTable();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        wishItemTxt = new javax.swing.JTextField();
        wishPriceTxt = new javax.swing.JTextField();
        postWishBtn = new javax.swing.JButton();
        unpostWishBtn = new javax.swing.JButton();
        jPanel5 = new javax.swing.JPanel();
        jScrollPane4 = new javax.swing.JScrollPane();
        boughtItemsTable = new javax.swing.JTable();
        jScrollPane5 = new javax.swing.JScrollPane();
        soldItemsTable = new javax.swing.JTable();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        userNameLabel = new javax.swing.JLabel();
        balanceLabel = new javax.swing.JLabel();
        mainMenuBar = new javax.swing.JMenuBar();
        marketMenu = new javax.swing.JMenu();
        connectMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        setTitle("Client");
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        allItemsTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        jScrollPane3.setViewportView(allItemsTable);

        refreshListBtn.setText("Refresh list");
        refreshListBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshListBtnActionPerformed(evt);
            }
        });

        buyBtn.setText("Buy selected");
        buyBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                buyBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 286, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(buyBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(refreshListBtn, javax.swing.GroupLayout.DEFAULT_SIZE, 93, Short.MAX_VALUE))
                .addContainerGap(162, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel3Layout.createSequentialGroup()
                        .addComponent(refreshListBtn)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 181, Short.MAX_VALUE)
                        .addComponent(buyBtn))
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Market", jPanel3);

        jScrollPane1.setViewportView(postedItemTable);

        jLabel1.setText("Item name:");

        jLabel2.setText("Price:");

        postItemBtn.setText("Post Item");
        postItemBtn.setName("addIItemBtn"); // NOI18N
        postItemBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                postItemBtnActionPerformed(evt);
            }
        });

        unpostItemBtn.setText("Unpost item");
        unpostItemBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unpostItemBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 286, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(itemNameTxt, javax.swing.GroupLayout.DEFAULT_SIZE, 186, Short.MAX_VALUE)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(priceTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(postItemBtn, javax.swing.GroupLayout.DEFAULT_SIZE, 110, Short.MAX_VALUE))))
                    .addComponent(unpostItemBtn))
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(itemNameTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(priceTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(postItemBtn))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 142, Short.MAX_VALUE)
                        .addComponent(unpostItemBtn))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)))
                .addContainerGap())
        );

        jTabbedPane1.addTab("My Posted Items", jPanel1);

        wishTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        jScrollPane2.setViewportView(wishTable);

        jLabel3.setText("Wish name:");

        jLabel4.setText("Price:");

        postWishBtn.setText("Wish Item");
        postWishBtn.setName("addIItemBtn"); // NOI18N
        postWishBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                postWishBtnActionPerformed(evt);
            }
        });

        unpostWishBtn.setText("Unpost wish");
        unpostWishBtn.setName("addIItemBtn"); // NOI18N
        unpostWishBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                unpostWishBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 286, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel3)
                            .addComponent(jLabel4))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel2Layout.createSequentialGroup()
                                .addComponent(wishPriceTxt, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(postWishBtn, javax.swing.GroupLayout.DEFAULT_SIZE, 109, Short.MAX_VALUE))
                            .addComponent(wishItemTxt, javax.swing.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)))
                    .addComponent(unpostWishBtn))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(wishItemTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(wishPriceTxt, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(postWishBtn))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 142, Short.MAX_VALUE)
                        .addComponent(unpostWishBtn))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 227, Short.MAX_VALUE)))
                .addContainerGap())
        );

        jTabbedPane1.addTab("Wish List", jPanel2);

        jPanel5.setLayout(new java.awt.GridLayout());

        jScrollPane4.setViewportView(boughtItemsTable);

        jPanel5.add(jScrollPane4);

        soldItemsTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        jScrollPane5.setViewportView(soldItemsTable);

        jPanel5.add(jScrollPane5);

        jTabbedPane1.addTab("Sold&Bought Items", jPanel5);

        jLabel5.setText("Username:");

        jLabel6.setText("Balance:");

        userNameLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

        balanceLabel.setFont(new java.awt.Font("Tahoma", 1, 11));

        marketMenu.setText("Market");

        connectMenuItem.setText("Register...");
        connectMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                connectMenuItemActionPerformed(evt);
            }
        });
        marketMenu.add(connectMenuItem);

        mainMenuBar.add(marketMenu);

        setJMenuBar(mainMenuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 562, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel5)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(userNameLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(balanceLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 67, Short.MAX_VALUE))
                .addContainerGap(427, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(userNameLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(balanceLabel)
                    .addComponent(jLabel6))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 18, Short.MAX_VALUE)
                .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 277, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-578)/2, (screenSize.height-399)/2, 578, 399);
    }// </editor-fold>//GEN-END:initComponents

private void postItemBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_postItemBtnActionPerformed
    try {
        if (!itemNameTxt.getText().isEmpty() && !priceTxt.getText().isEmpty()) {
            Float price = Float.parseFloat(priceTxt.getText());
            final MarketItem item = new MarketItemImpl(itemNameTxt.getText(), price, client.getUserName());
            //postedItemsModel.addMarketItem(item);
            Runnable addItemToMarket = new Runnable() {
                @Override
                public void run() {
                    client.postItem(item);
                }
            };
            (new Thread(addItemToMarket)).start();
        }
    } catch (NumberFormatException ex) {
        JOptionPane.showConfirmDialog(null, "Price is not correctly introduced. Try again.", "Error", JOptionPane.INFORMATION_MESSAGE);
    }
}//GEN-LAST:event_postItemBtnActionPerformed

private void postWishBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_postWishBtnActionPerformed
    try {
        if (!wishItemTxt.getText().isEmpty() && !wishPriceTxt.getText().isEmpty()) {
            Float price = Float.parseFloat(wishPriceTxt.getText());
            final MarketItem item = new MarketItemImpl(wishItemTxt.getText(), price, client.getUserName());
            //wishItemsModel.addMarketItem(item);
            Runnable addItemToMarket = new Runnable() {
                @Override
                public void run() {
                    client.postWish(item);
                }
            };
            (new Thread(addItemToMarket)).start();
        }
    } catch (NumberFormatException ex) {
        JOptionPane.showConfirmDialog(null, "Price is not correctly introduced. Try again.", "Error", JOptionPane.INFORMATION_MESSAGE);
    }
}//GEN-LAST:event_postWishBtnActionPerformed

private void connectMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_connectMenuItemActionPerformed
    // Connect to market
    (new ConnectDialog(this, true)).setVisible(true);
}//GEN-LAST:event_connectMenuItemActionPerformed

private void refreshListBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshListBtnActionPerformed
    Runnable getAllItemsTask = new Runnable() {
        @Override
        public void run() {
            client.getItems();
        }
    };
    (new Thread(getAllItemsTask)).start();
}//GEN-LAST:event_refreshListBtnActionPerformed

private void unpostItemBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unpostItemBtnActionPerformed
    final MarketItem item = postedItemsModel.getMarketItem(postedItemTable.getSelectedRow());
    if (item == null) {
        return;
    }
    Runnable unpostTask = new Runnable() {
        @Override
        public void run() {
            client.unpostItem(item);
        }
    };
    new Thread(unpostTask).start();
}//GEN-LAST:event_unpostItemBtnActionPerformed

private void unpostWishBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unpostWishBtnActionPerformed
    final MarketItem wish = wishItemsModel.getMarketItem(wishTable.getSelectedRow());
    if (wish == null) {
        return;
    }
    Runnable unpostTask = new Runnable() {
        @Override
        public void run() {
            client.unpostWish(wish);
        }
    };
    new Thread(unpostTask).start();
}//GEN-LAST:event_unpostWishBtnActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        Runnable exitTask = new Runnable() {
            @Override
            public void run() {
                client.unregister();
                System.exit(0);
            }
        };
        new Thread(exitTask).start();
    }//GEN-LAST:event_formWindowClosing

    private void buyBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buyBtnActionPerformed
        final MarketItem item = allItemsModel.getMarketItem(allItemsTable.getSelectedRow());
        if (item == null) {
            return;
        }
        Runnable buyTask = new Runnable() {
            @Override
            public void run() {
                client.buyItem(item);
            }
        };
        new Thread(buyTask).start();
    }//GEN-LAST:event_buyBtnActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(final String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ClientUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>


        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ClientUI(args).setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTable allItemsTable;
    private javax.swing.JLabel balanceLabel;
    private javax.swing.JTable boughtItemsTable;
    private javax.swing.JButton buyBtn;
    private javax.swing.JMenuItem connectMenuItem;
    private javax.swing.JTextField itemNameTxt;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JScrollPane jScrollPane5;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JMenuBar mainMenuBar;
    private javax.swing.JMenu marketMenu;
    private javax.swing.JButton postItemBtn;
    private javax.swing.JButton postWishBtn;
    private javax.swing.JTable postedItemTable;
    private javax.swing.JTextField priceTxt;
    private javax.swing.JButton refreshListBtn;
    private javax.swing.JTable soldItemsTable;
    private javax.swing.JButton unpostItemBtn;
    private javax.swing.JButton unpostWishBtn;
    private javax.swing.JLabel userNameLabel;
    private javax.swing.JTextField wishItemTxt;
    private javax.swing.JTextField wishPriceTxt;
    private javax.swing.JTable wishTable;
    // End of variables declaration//GEN-END:variables

    @Override
    public void updateAllItems(final List<MarketItem> items) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                allItemsModel.setMarketItemList(items);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void alertWishItem(final MarketItem item) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                wishItemsModel.removeMarketItem(item.getMarketItemId());
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateOnPostedItemSold(final MarketItem item) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                postedItemsModel.removeMarketItem(item.getMarketItemId());
                soldItemsModel.addMarketItem(item);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void showBuyConfirmationDialog() {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, "Purchase was successful.", "Information", JOptionPane.INFORMATION_MESSAGE);

            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void showItemSoldNotificationMessage(final MarketItem item) {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, "Posted item was sold. Item id: " + item.getMarketItemId(), "Information", JOptionPane.INFORMATION_MESSAGE);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateBalance(final float balance) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                balanceLabel.setText(Float.toString(balance));
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void connectToMarket(String userName) {
        setTitle("Client --- Registering into market...");
        client.setUserName(userName);
        userNameLabel.setText(userName);
        Runnable registerTask = new Runnable() {
            @Override
            public void run() {
                if (client.getAccount() == null) {
                    client.createAccount();
                }
                client.register();
            }
        };
        (new Thread(registerTask)).start();
    }

    @Override
    public void showBuyWishItemDialog(final MarketItem item) {
        final java.awt.Frame c = this;

        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                BuyWishDialog buyDlg = new BuyWishDialog(c, true, item);
                buyDlg.setVisible(true);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void buyItem(final MarketItem item) {
        Runnable buyItem = new Runnable() {
            @Override
            public void run() {
                client.buyItem(item);
            }
        };
        (new Thread(buyItem)).start();
    }

    @Override
    public void updateTitle(final String msg) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                setTitle("Client --- " + msg);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateOnItemBought(final MarketItem item) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                boughtItemsModel.addMarketItem(item);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateOnPostItem(final MarketItem item) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                postedItemsModel.addMarketItem(item);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateOnPostWish(final MarketItem wish) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                wishItemsModel.addMarketItem(wish);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateOnUnpostItem(final MarketItem item) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                postedItemsModel.removeMarketItem(item.getMarketItemId());
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void updateOnUnpostWish(final MarketItem wish) {
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                wishItemsModel.removeMarketItem(wish.getMarketItemId());
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void showRejectedNotificationMessage(final String message) {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, message, "Exception", JOptionPane.ERROR_MESSAGE);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void showExceptionNotificationMessage(final String message) {
        final java.awt.Component c = this;
        Runnable updateUI = new Runnable() {
            @Override
            public void run() {
                JOptionPane.showMessageDialog(c, message, "Exception", JOptionPane.ERROR_MESSAGE);
            }
        };
        try {
            SwingUtilities.invokeAndWait(updateUI);
        } catch (InterruptedException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ClientUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
